package com.xuecheng.content.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuecheng.commons.constants.CourseConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.CourseAuditDto;
import com.xuecheng.commons.model.dto.CourseBaseDto;
import com.xuecheng.commons.model.dto.CourseDto;
import com.xuecheng.commons.model.dto.PageRequest;
import com.xuecheng.commons.model.vo.CourseBaseVo;
import com.xuecheng.commons.model.vo.PageResponseResult;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.content.config.MinioTemplate;
import com.xuecheng.content.domain.CourseBase;
import com.xuecheng.content.domain.Teachplan;
import com.xuecheng.content.mapper.CourseBaseMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.content.service.TeachplanService;
import com.xuecheng.web.exception.BusinessException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 课程基本信息 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2022-09-14
 */
@Service
public class CourseBaseServiceImpl extends ServiceImpl<CourseBaseMapper, CourseBase> implements CourseBaseService {

    @Override
    public ResponseResult findByPage(PageRequest pageRequest, CourseDto dto) {

        //1.构建分页
        Page<CourseBase> page = new Page<>(pageRequest.getPageNo(), pageRequest.getPageSize());
        //2.构建条件
        LambdaQueryWrapper<CourseBase> qw = new LambdaQueryWrapper<>();
        //2-1 课程名称
        qw.like(StrUtil.isNotEmpty(dto.getCourseName()),CourseBase::getName,dto.getCourseName());
        //2-2 课程状态
        qw.eq(StrUtil.isNotEmpty(dto.getAuditStatus()),CourseBase::getStatus,dto.getAuditStatus());    
        //2-3 课程类型
        qw.eq(StrUtil.isNotEmpty(dto.getTeachmode()),CourseBase::getTeachmode,dto.getTeachmode());
        page = this.page(page, qw);
        //4.转Vo
        List<CourseBaseVo> voList = BeanHelper.copyWithCollection(page.getRecords(), CourseBaseVo.class);
        return PageResponseResult.okResult(page.getTotal(),voList);
    }

    @Autowired
    TeachplanService teachplanService;

    @Override
    public ResponseResult addCourse(CourseBaseDto courseBaseDto) {
        //1.检验参数合法性
        if (!StrUtil.isAllNotEmpty(courseBaseDto.getName(), courseBaseDto.getTeachmode())) {
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        //2.Dto转实体Entity
        CourseBase courseBase = BeanHelper.copyProperties(courseBaseDto, CourseBase.class);
        //3.初始化课程
        courseBase.setAuditStatus(CourseConstants.AUDIT_UNPAST_STATUS);//课程审核状态-初始为未通过
        courseBase.setPlanNum(0);//课程小节数量-初始为0
        courseBase.setCreateDate(new Date());//新增时间
        //4.保存到数据库
        boolean isSuccess = this.save(courseBase);
        if (!isSuccess) {
            throw new BusinessException(ErrorCode.ADDEERROR);
        }
        //5.初始化课程计划（一级大纲）
        Teachplan teachplan = new Teachplan();
        teachplan.setCourseId(courseBase.getId());
        teachplan.setPname(courseBase.getName());
        teachplan.setGrade(1);
        teachplan.setParentid(0L);
        teachplan.setDescription(courseBase.getDescription());
        teachplan.setCreateDate(new Date());
        teachplanService.save(teachplan);

        //6.返回课程ID
        HashMap hashMap = new HashMap();
        hashMap.put("courseBaseId", courseBase.getId());
        return ResponseResult.okResult(hashMap);
    }

    @Override
    public ResponseResult updateCourse(CourseBaseDto courseBaseDto) {
        //1.检验参数的合法性
        if ((ObjectUtil.isEmpty(courseBaseDto.getId())
                ||StrUtil.isEmpty(courseBaseDto.getDescription())
                ||StrUtil.isEmpty(courseBaseDto.getName()))) {
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        //2.检验课程状态
        //2-1 根据ID查找数据库
        CourseBase courseBase = this.getById(courseBaseDto.getId());

        if (( StrUtil.equals(courseBase.getAuditStatus(), CourseConstants.AUDIT_COMMIT_STATUS)
                 ||StrUtil.equals(courseBase.getAuditStatus(),CourseConstants.AUDIT_PUBLISHED_STATUS)
                 ||StrUtil.equals(courseBase.getAuditStatus(),CourseConstants.AUDIT_PASTED_STATUS))) {
            throw new BusinessException(ErrorCode.MEDIABINDERROR);
        }
        //3.dto 转实体
        BeanUtil.copyProperties(courseBaseDto,courseBase);
        //设置为未发布状态
        courseBase.setAuditStatus(CourseConstants.AUDIT_UNPAST_STATUS);
        //4.更新数据库
        this.updateById(courseBase);
        //5.更新课程计划(一级大纲)
        //5-1 先根据课程ID和计划等级查询数据库
        LambdaQueryWrapper<Teachplan> qw = new LambdaQueryWrapper<>();
        qw.eq(Teachplan::getCourseId,courseBase.getId());
        qw.eq(Teachplan::getGrade,1);
        Teachplan teachplan = teachplanService.getOne(qw);
        // 5-2 重新设置参数
        teachplan.setPname(courseBase.getName());//一级大纲名称(课程信息名称)
        teachplan.setDescription(courseBase.getDescription());
        teachplan.setChangeDate(new Date());
        //5-3 更新数据库
        teachplanService.updateById(teachplan);


        //6.返回课程ID
        HashMap map = new HashMap();
        map.put("courseBaseId",courseBase.getId());


        return ResponseResult.okResult(map);
    }

    // 课程删除
    @Override
    public ResponseResult deleteCourse(Long courseId) {
        // 1.校验课程状态
        // 1-1 根据id查询数据库
        CourseBase courseBase = this.getById(courseId);
        // 1-2 判断
        if (courseBase.getAuditStatus().equals(CourseConstants.AUDIT_PUBLISHED_STATUS)) {
            throw  new BusinessException(ErrorCode.MEDIABINDERROR);
        }

        // 该课程如果有 二级、三级 数据则不允许删除
        LambdaQueryWrapper<Teachplan> qw = new LambdaQueryWrapper<>();
        qw.eq(Teachplan::getCourseId,courseId);
        long count = teachplanService.count(qw);
        if (count>1) {
            throw new BusinessException(ErrorCode.DELETEERROR);
        }

        // 2.执行删除
        this.removeById(courseId);
        // 同时删除一级大纲
        teachplanService.remove(qw);


        // 3.返回成功
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult commitCourse(Long courseBaseId) {
        //构建课程对象
        CourseBase courseBase = new CourseBase();
        //设置ID和课程状态
        courseBase.setId(courseBaseId);
        courseBase.setAuditStatus(CourseConstants.AUDIT_COMMIT_STATUS);
        //更新数据库
        this.updateById(courseBase);

        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult approveCourseCommit(CourseAuditDto courseAuditDto) {
        //从数据库获取CourseBase
        Long courseBaseId = courseAuditDto.getCourseBaseId();
        CourseBase courseBaseById = this.getById(courseBaseId);
        //设置新值
        courseBaseById.setAuditStatus(courseAuditDto.getAuditStatus());
        courseBaseById.setAuditMind(courseAuditDto.getAuditMind());
        //更新数据库
        this.updateById(courseBaseById);

        return ResponseResult.okResult();
    }

    @Autowired
    private CoursePubServiceImpl coursePubService;
    @Autowired
    private MinioTemplate minioTemplate;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Override
    public ResponseResult offlineCourse(Long courseId) {
        //1.参数校验,只有已发布的才可以下架
        CourseBase courseBase = this.getById(courseId);
        String auditStatus = courseBase.getAuditStatus();

        if (!auditStatus.equals(CourseConstants.AUDIT_PUBLISHED_STATUS)) {
            throw new BusinessException(ErrorCode.DATAERROR);
        }
        //2.修改课程的状态
        courseBase.setAuditStatus(CourseConstants.AUDIT_UNLINE_STATUS);
        this.updateById(courseBase);
        //3.删除课程发布的数据
        coursePubService.removeById(courseId);
        //4.删除Minio静态文件
        String fileName = "/pages/" + courseId + ".html";
        minioTemplate.delete(fileName);
        //5.MQ发送消息到search服务，删除es课程发布表的数据
        rabbitTemplate.convertAndSend("content-exchange","course-offline",courseId.toString());
        //6.return
        return ResponseResult.okResult();
    }
}
